﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Entity.IRepository.Project;
using Entity.ProjectEnt;
using Logic.Repository.Project;
using ZFine.Code;
using ZFine.Domain.Entity;

namespace ZFine.Application.Project
{
    public class WorkPlanApp
    {
        private IWorkPlanRespository service = new WorkPlanRespository();
        private GudaoCarApp gudaocarApp = new GudaoCarApp();
        private PathwayApp PathwayserverApp = new PathwayApp();
        private PositionRecordApp positoonapp = new PositionRecordApp();
        public List<WorkPlanEntity> GetList()
        {
            return service.IQueryable().ToList();
        }
        public List<WorkPlanEntity> GetList(Expression<Func<WorkPlanEntity, bool>> predicate)
        {
            return service.IQueryable(predicate).ToList();
        }
        public List<WorkPlanEntity> GetList(Pagination pagination, string keyword)
        {
            var expression = ExtLinq.True<WorkPlanEntity>();
            expression = expression.And(t => t.State == true);
            return service.FindList(expression, pagination);
        }
        public List<WorkPlanEntity> GetListD(Pagination pagination, string keyword)
        {
            var expression = ExtLinq.True<WorkPlanEntity>();
            expression = expression.And(t => t.State == true);
            return service.FindList(expression, pagination);
        }
        public WorkPlanEntity GetForm(string keyValue)
        {
            return service.FindEntity(keyValue);
        }
        public int DeleteForm(string keyValue)
        {
            var local = service.FindEntity(keyValue);
            if (local != null)
            {
                local.State = false;
                return service.Update(local);
            }
            else
            {
                return -1;
            }
        }
        public int SubmitForm(WorkPlanEntity ServiceEntity, string keyValue)
        {
            var LoginInfo = OperatorProvider.Provider.GetCurrent();
            if (LoginInfo != null)
            {
                if (!string.IsNullOrEmpty(keyValue))
                {
                    ServiceEntity.Modify(keyValue);
                    return service.Update(ServiceEntity);
                }
                else
                {
                    ServiceEntity.Create();
                    ServiceEntity.State = true;
                    return service.Insert(ServiceEntity);
                }
            }
            return -1;
        }

        /// <summary>
        /// 添加计划
        /// </summary>
        /// <param name="objlist">批量计划任务</param>
        /// <param name="playstring">计划串</param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public int SubmitAddplay(List<ClientPlay> objlist, string playstring,string Planmun,string SendTime,string SendTime1, ref string msg)
        {
            #region 判断入车和出车完成后股道中车辆是否正确
            bool isAllowPlay = false;
            var orderlist = (from V in objlist group V by V.fangfa into g select g).ToList();
            List<int> fangfasum = new List<int>();
            foreach (var varitem in orderlist)
            {
                var temp = varitem.ToList().Sum(f => f.cheshu);
                fangfasum.Add(temp);
            }
            if (fangfasum.Count >= 2)
            {
                if (fangfasum[0] == fangfasum[1])
                {
                    isAllowPlay = true;
                }
            }
            if (!isAllowPlay)
            {
                msg = "方法总和有误，无法创建此计划";
                return -2;
            }
            #endregion
            #region 将各股道中的信息分组整合
            int code = 0;
            List<PathwayEntity> AllPathwaylist=new List<PathwayEntity>();
            var gudaoinfo = getgudaoAllinfo(ref  AllPathwaylist);
            Dictionary<string, List<GudaoCarEntity>> thisgudaolsit = new Dictionary<string, List<GudaoCarEntity>>();
            foreach (var item in gudaoinfo)
            {
                if (item.ToList()[0].BelongCarriage != null)
                {

                    thisgudaolsit.Add(item.Key.Name, item.OrderByDescending(f => f.CarGudaoIndex).ToList());
                }
                else
                {
                    thisgudaolsit.Add(item.Key.Name, new List<GudaoCarEntity>());
                }
            }
            foreach (var item in AllPathwaylist)//将空股道信息也添加进来
            {
                if (thisgudaolsit.Keys.ToList().Find(f => f.Equals(item.Name)) == null)
                {
                    thisgudaolsit.Add(item.Name, new List<GudaoCarEntity>());
                }
            }
            #endregion
            #region 判断股道中是否可以顺利完成计划（无排序）
            //排出的车辆信息(堆栈stack:先进后出)
            Stack<GudaoCarEntity> xinullgudaocarlist = new Stack<GudaoCarEntity>();
            Stack<GudaoCarEntity> dongnullgudaocarlist = new Stack<GudaoCarEntity>();
            //nullgudaocarlist.Push(new GudaoCarEntity());
            //nullgudaocarlist.Pop();
            for (int i = 0; i < objlist.Count; i++)
            {
                //+是从股道里往出拉车 -是往股道里加车
                if (objlist[i].fangfa == "+" && objlist[i].fangxiang == "西")
                {
                    code = xiRemoveGudao(xinullgudaocarlist, thisgudaolsit, objlist[i], ref msg);
                    if (code < 0)
                    {
                        return code;
                    }
                }
                else if (objlist[i].fangfa == "+" && objlist[i].fangxiang == "东")
                {
                    code = xiRemoveGudao(dongnullgudaocarlist, thisgudaolsit, objlist[i], ref msg);
                    if (code < 0)
                    {
                        return code;
                    }
                }
                else if (objlist[i].fangfa == "-" && objlist[i].fangxiang == "西")
                {
                    code = AddToGudao(xinullgudaocarlist, thisgudaolsit, objlist[i], ref msg);
                    if (code < 0)
                    {
                        return code;
                    }
                }
                else if (objlist[i].fangfa == "-" && objlist[i].fangxiang == "东")
                {
                    code = AddToGudao(dongnullgudaocarlist, thisgudaolsit, objlist[i], ref msg);
                    if (code < 0)
                    {
                        return code;
                    }
                }
            }
            #endregion

            #region 创建计划，插入数据库
            WorkPlanEntity newworkplan = new WorkPlanEntity();
            newworkplan.Create();
            newworkplan.PlayNum = Planmun;
            if (!string.IsNullOrEmpty(SendTime))
            {
                newworkplan.BeginDateTime = Convert.ToDateTime(SendTime);
            }
            if (!string.IsNullOrEmpty(SendTime1))
            {
                newworkplan.EndDateTime = Convert.ToDateTime(SendTime1);
            }
            newworkplan.BianZhiDateTime = DateTime.Now;
            newworkplan.BianZhiPlan = playstring;
            newworkplan.State = true;

            OperationGudaoCarEntity OperationGudaoCarEntity = new OperationGudaoCarEntity();
            OperationGudaoCarEntity.Create();
            OperationGudaoCarEntity.WorkPlan = newworkplan;
            OperationGudaoCarEntity.State = true;
            OperationGudaoCarEntity.OperationType = 2;
            OperationGudaoCarEntity.OperationTime = DateTime.Now;
            OperationGudaoCarEntity.IsExecute = false;
            var LoginInfo = OperatorProvider.Provider.GetCurrent();
            if (LoginInfo != null)
            {
                OperationGudaoCarEntity.OperationPersion = new UserEntity() { F_Id = LoginInfo.UserId };
            }
          
            //OperationGudaoCarEntity.OperationPersion
            var thispaiban = positoonapp.GetForm(f => f.State == true);
            if (thispaiban != null)//有效班期id
            {
                OperationGudaoCarEntity.Banci = thispaiban.F_Id;
            }

            if (thispaiban != null&&thispaiban.DispatcherUser != null)
            {
                newworkplan.DiaoDuPerson = thispaiban.DispatcherUser;
            }

            if (thispaiban != null && thispaiban.DiaochezhangUser != null)
            {
                newworkplan.DiaoChePersion = thispaiban.DiaochezhangUser;
            }

            //OperationGudaoCarEntity.Banci = "";

            code = service.SubmitPlan(OperationGudaoCarEntity, newworkplan);

            #endregion

            if (code < 0)
            {
                msg = "操作失败,请稍后重试";
            }
            return code;
        }

        /// <summary>
        /// 往股道里加车
        /// </summary>
        /// <param name="xinullgudaocarlist"></param>
        /// <param name="thisgudaolsit"></param>
        /// <param name="clientPlay"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        private int AddToGudao(Stack<GudaoCarEntity> xinullgudaocarlist, Dictionary<string, List<GudaoCarEntity>> thisgudaolsit, ClientPlay clientPlay, ref string msg)
        {
            int code = 0;
            int chucount = clientPlay.cheshu;
            if (chucount > xinullgudaocarlist.Count)
            {
                msg = string.Format("计划创建时有错误，操作股道{0}，方法{1}，数量{2}，方向：{3},错误信息：往股道里加车不足，非股道中的车数：{4}", clientPlay.gudao,
                    clientPlay.fangfa, clientPlay.cheshu, clientPlay.fangxiang, xinullgudaocarlist.Count);
                code = -2;
            }
            else
            {
                //int popcount = xinullgudaocarlist.Count;
                for (int i = 0; i < chucount; i++)
                {
                    var temp = xinullgudaocarlist.Peek();
                    xinullgudaocarlist.Pop();
                    thisgudaolsit[clientPlay.gudao].Add(temp);
                }
            }
            return code;
        }

        /// <summary>
        /// 从股道里往出拉车 西方向
        /// </summary>
        /// <param name="xinullgudaocarlist">转变股道 西/东</param>
        /// <param name="thisgudaolsit">所有股道中信息</param>
        /// <param name="msg">返回消息</param>
        /// <returns></returns>
        private int xiRemoveGudao(Stack<GudaoCarEntity> xinullgudaocarlist, Dictionary<string, List<GudaoCarEntity>> thisgudaolsit, ClientPlay clientPlay, ref string msg)
        {
            int code = 0;
            int chucount = clientPlay.cheshu;
            if (chucount > thisgudaolsit[clientPlay.gudao].Count)
            {
                msg = string.Format("计划创建时有错误，操作股道{0}，方法{1}，数量{2}，方向：{3},错误信息：从股道里往出拉车不足，股道中实有车数{4}", clientPlay.gudao,
                    clientPlay.fangfa, clientPlay.cheshu, clientPlay.fangxiang, thisgudaolsit[clientPlay.gudao].Count);
                code = -2;
            }
            else
            {
                for (int i = 0; i < chucount; i++)
                {
                    xinullgudaocarlist.Push(thisgudaolsit[clientPlay.gudao][i]);
                }
            }
            return code;
        }

        /// <summary>
        /// 获取个股道中的信息
        /// </summary>
        /// <returns></returns>
        public List<IGrouping<PathwayEntity, GudaoCarEntity>> getgudaoAllinfo(ref List<PathwayEntity> gudaoAlllist)
        {
            var reuslt = gudaocarApp.GetListInclude(f => f.State == true);//获取当前有效的所有股道上的车
            #region 将空股道填入
             gudaoAlllist = PathwayserverApp.GetList(f => f.State == true);
            if (gudaoAlllist != null && gudaoAlllist.Count > 0)
            {
                gudaoAlllist.ForEach(f =>
                {
                    bool exit = gudaocarApp.GetNoTrackObj(z => z.BelongPathway.F_Id == f.F_Id && f.State == true) !=
                                null
                        ? false
                        : true;
                    if (exit)
                    {
                        var temp = new GudaoCarEntity();
                        temp.BelongPathway = f;
                        reuslt.Add(temp);
                    }
                });
            }
            var result = (from gudaoEntity in reuslt group gudaoEntity by gudaoEntity.BelongPathway into g select g).ToList();
            #endregion
            return result;
        }
    }

    public class gudaohecheT
    {
        public string gudanname { get; set; }
        public string pingming { get; set; }
        public int carmun { get; set; }
    }

    public class ClientPlay
    {
        public string fangxiang { get; set; }
        public string gudao { get; set; }
        public string fangfa { get; set; }
        public int cheshu { get; set; }
        public string jishi { get; set; }

    }
}
